﻿using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using Halk.Model;
using Halk.Utils;

namespace Halk.Builder
{
    public class HtmlBuilder : BuilderBase
    {
        private readonly Config.ConfigInfo _config;

        public HtmlBuilder(Config.ConfigInfo config)
        {
            _config = config;
        }

        private readonly TemplateInfo _template = new TemplateInfo();

        private int _indexCols = 0;

        private string GetDirValue(string key)
        {
            if (_template.JieqiArticleConfigs.ContainsKey(key)
                && _template.JieqiArticleConfigs[key].Contains(":"))
            {
                string dir = string.Format(@"{0}\files\article\{1}", _config.FilePath,
                                           _template.JieqiArticleConfigs[key]);
                return dir;
            }
            return "";
        }

        private string GetUrlValue(string key)
        {
            if (_template.JieqiArticleConfigs.ContainsKey(key) &&
                !string.IsNullOrEmpty(_template.JieqiArticleConfigs[key]))
            {
                string url = string.Format(@"{0}\files\article\{1}", _template.JieqiDefine["JIEQI_URL"],
                                           _template.JieqiArticleConfigs[key]);
                return url;
            }
            return "";
        }

        public void LoadDefineFile()
        {
            string strDefine = Utils.XFile.ReadFile(_config.FilePath + @"\configs\define.php");
            MatchCollection matchs = Regex.Matches(strDefine, "define\\('(.+?)','(.*)'\\);");
            foreach (Match match in matchs)
            {
                _template.JieqiArticleConfigs[match.Groups[1].Value] = match.Groups[2].Value;
            }
            string strSort = Utils.XFile.ReadFile(_config.FilePath + @"\configs\article\sort.php");
            matchs = Regex.Matches(strSort,
                                   "jieqiSort\\['article'\\]\\[(\\d*)\\] = array\\('layer' => '0', 'caption' => '(.+?)', 'shortname'");
            _template.JieqiSort[0] = "未知分类";
            foreach (Match match in matchs)
            {
                _template.JieqiSort[int.Parse(match.Groups[1].Value)] = match.Groups[2].Value;
            }
            string strConfigs = Utils.XFile.ReadFile(_config.FilePath + @"\configs\article\configs/php");
            matchs = Regex.Matches(strConfigs, "jieqiConfigs\\['article'\\]\\['(.+?)'\\] \\= '(.*)';");
            foreach (Match match in matchs)
            {
                _template.JieqiArticleConfigs[match.Groups[1].Value] = match.Groups[2].Value;
            }
            _indexCols = _template.JieqiArticleConfigs.ContainsKey("indexcols")
                             ? int.Parse(_template.JieqiArticleConfigs["indexcols"])
                             : 4;
            _template.HtmlDir = GetDirValue("htmldir");
            _template.HtmlUrl = GetUrlValue("htmldir");
            _template.TxtDir = GetDirValue("txtdir");
            _template.TxtUrl = GetUrlValue("txtdir");
            _template.OpfDir = GetDirValue("opfdir");
            _template.OpfUrl = GetUrlValue("opfurl");
            _template.AttachDir = GetDirValue("attachdir");
            _template.AttachUrl = GetUrlValue("attachurl");
        }

        public void LoadTheme()
        {
            _template.TempletsIndexHtml =
                Utils.XFile.ReadFile(_config.FilePath + @"\modules\article\templates\index.html");
            _template.TempletsContent = Utils.XFile.ReadFile(_config.FilePath + @"\modules\article\");
            InitializeReplaceTemplete(_template.TempletsIndexHtml);
            InitializeReplaceTemplete(_template.TempletsContent);
            const string regex1 =
                "\\{\\?if\\s+\\$indexrows\\[i\\]\\.([^=]+?)\\s*==\\s*\"\"\\?\\}(.+?)\\{\\?else\\?\\}(.+?)\\{\\?/if\\?\\}";
            const string regex2 =
                "\\{\\?section name=i loop=\\$indexrows\\?\\}(.*)\\{\\?if \\$indexrows\\[i\\]\\.ctype == \"volume\"\\?\\}(.+?)\\{\\?else\\?\\}(.+?)\\{\\?/if\\?\\}(.*)\\{\\?/section\\?\\}";
            const string regex3 = @"\\{\\?section name=i loop=\\$chapters\\?\\}(.+?)\\{\\?/section\?\\}";
            const string regex4 =
                "\\{\\?section name=i loop=\\$indexrows\\?\\}(.+?)\\{\\?if \\$indexrows\\[i\\]\\.ctype == \"volume\"\\?\\}(.+?)\\{\\?else\\?\\}(.+?)\\{\\?/if\\?\\}(.+?)\\{\\?/section\\?\\}";
            string strTemp;
            MatchCollection matchs = Regex.Matches(_template.TempletsIndexHtml, regex1, RegexOptions.Singleline);
            foreach (Match match in matchs)
            {
                var strArr = new List<string>
                                 {
                                     match.Groups[2].Value.Replace("&nbsp;", " "),
                                     match.Groups[3].Value.Replace("&nbsp;", " ")
                                 };
                _template.TempletsIndexchapterlist[match.Groups[1].Value] = strArr;
            }
            _template.TempletsIndexhtml = Regex.Replace(_template.TempletsIndexHtml, regex1, "章节$1",
                                                         RegexOptions.Singleline);
            matchs = Regex.Matches(_template.TempletsIndexhtml, regex2, RegexOptions.Singleline);
            foreach (Match match in matchs)
            {
                _template.TempletsIndextop = match.Groups[1].Value;
                _template.TempletsIndexvolume = match.Groups[2].Value;
                _template.TempletsIndexchapter = match.Groups[3].Value;
                _template.TempletsIndexbottom = match.Groups[4].Value;
            }
        }

        private  string InitializeReplaceTemplete(string val)
        {
            return val;
        }

        public bool CreateChapterHtml(Model.ArticleInfo article, Model.ChapterInfo chapter)
        {
            var content = _template.TempletsContent;
            content =
                content.Replace(
                    "<{if $authorid > 0}><a href=\"<{$article_dynamic_url}>/userinfo.php?id=<{$authorid}>\" target=\"_blank\"><{$author}></a><{else}><{$author}><{/if}>",
                    "<{$author}>");
            content = content.Replace("<{$author}>", article.author);
            content = content.Replace("<{$article_title}>", article.articlename);
            content = content.Replace("<{$jieqi_title}>", _config.WebName);
            content = content.Replace("<{$sortname}>", article.sortname);
            content = content.Replace("<{$jieqi_sitename}>", _template.JieqiDefine["JIEQI_SITE_NAME"]);
            content = content.Replace("<{$jieqi_charset}>", _config.Charset);
            content = content.Replace("<{$meta_keywords}>", _template.JieqiDefine["JIEQI_META_KEYWORDS"]);
            content = content.Replace("<{$meta_description}>", _template.JieqiDefine["JIEQI_META_DESCRIPTION"]);
            content = content.Replace("<{$meta_author}>", "meta_author");
            content = content.Replace("<{$meta_copyright}>", _template.JieqiDefine["JIEQI_META_COPYRIGHT"]);
            content = content.Replace("<{$new_url}>", _template.JieqiDefine["JIEQI_URL"]);
            content = content.Replace("<{$indexrows[i].vname}>", chapter.chaptername);
            if (chapter.previewpage!=-1)
            {
                content = content.Replace("{?$preview_page?}",
                                          chapter.previewpage + _template.JieqiArticleConfigs["htmlfile"]);
                content = content.Replace("{?$preview_chapterid?}", chapter.previewpage.ToString(CultureInfo.InvariantCulture));
                content = content.Replace("{?$preview_chapteridd?}", chapter.previewpage + "/");
            }
            else
            {
                content = content.Replace("{?$preview_page?}", "index" + _template.JieqiArticleConfigs["htmlfile"]);
                content = content.Replace("{?$preview_chapterid?}", "");
                content = content.Replace("{?$preview_chapteridd?}", "");
            }
            if (chapter.nextpage!=-1)
            {
                content = content.Replace("{?$next_page?}", chapter.nextpage + _template.JieqiArticleConfigs["htmlfile"]);
                content = content.Replace("{?$next_chapterid?}", chapter.nextpage.ToString(CultureInfo.InvariantCulture));
                content = content.Replace("{?$next_chapteridd?}", chapter.nextpage + "/");
            }
            else
            {
                content = content.Replace("{?$next_page?}", "index" + _template.JieqiArticleConfigs["htmlfile"]);
                content = content.Replace("{?$next_chapterid?}", "");
                content = content.Replace("{?$next_chapteridd?}", "");
            }
            content = content.Replace("{?$index_page?}", "index" + _template.JieqiArticleConfigs["htmlfile"]);
            content = content.Replace("{?$url_indexpage?}", "index" + _template.JieqiArticleConfigs["htmlfile"]);
            content = content.Replace("{?$article_id?}", article.articleid.ToString(CultureInfo.InvariantCulture));
            content = content.Replace("{?$chapter_id?}", chapter.chapterid.ToString(CultureInfo.InvariantCulture));
            content = content.Replace("{?$dynamic_url?}", _template.JieqiDefine["JIEQI_URL"]);
            content = content.Replace("{?$url_bookroom?}", _template.JieqiDefine["JIEQI_URL"] + "/modules/article/");
            content = content.Replace("{?$url_articleinfo?}",
                                      _template.JieqiDefine["JIEQI_URL"] + "/modules/article/articleinfo.php?id=" +
                                      article.articleid.ToString(CultureInfo.InvariantCulture));
            content = content.Replace("{?$jieqi_content?}", GetChapterUrl(chapter));
            content = ReplaceTemplate(content, article);
            var path = string.Format("{0}/{1}/{2}", _template.HtmlDir, article.articleid/1000, article.articleid);
            if(System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }
            path += string.Format("/{0}{1}", chapter.chapterid, _template.JieqiArticleConfigs["htmlfile"]);

            return XFile.WriteFile(path, content);
        }

        private string GetChapterUrl(Model.ChapterInfo chapter)
        {
            if (_config.SourceFlag.Equals("copy"))
            {
                string sourcePath = string.Format(@"{0}\files\article\txt\{1}\{2}\{3}.txt", _config.SourceFilePath,
                                                  chapter.sourcearticleid/1000, chapter.sourcearticleid,
                                                  chapter.sourcechapterid);
                string targetPath = string.Format(@"{0}\files\article\txt\{1}\{2}\{3}.txt", _config.FilePath,
                                                  chapter.articleid/1000, chapter.articleid, chapter.chapterid);
                string content = Utils.XFile.ReadFile(sourcePath);
                content += string.Format("document.write({0});", content);
                if (Utils.XFile.WriteFile(sourcePath, content))
                {
                    return targetPath;
                }
            }
            else if (_config.SourceFlag.Equals("js"))
            {
                string txtUrl = string.Format("<scrpit src=\"{0}/files/article/txt/{1}/{2}/{3}.txt\" />",
                                              _config.TargetDomain,
                                              _template.TxtUrl, chapter.sourcearticleid/1000, chapter.sourcearticleid,
                                              chapter.sourcechapterid);
                return txtUrl;
            }
            return "";
        }

        private string ReplaceTemplate(string input, Model.ArticleInfo article)
        {
            var result = input;
            result = result.Replace("{?$author?}", article.author);
            result = result.Replace("{?$article_title?}", article.articlename);
            result = result.Replace("{?$book_title?}", article.articlename);
            result = result.Replace("{?$intro?}", article.intro);
            result = result.Replace("{?$jieqi_title?}",string.Format("{0} {1}", article.lastvolume, article.lastchapter));
            result = result.Replace("{?$jieqi_volume?}", article.lastvolume);
            result = result.Replace("{?$jieqi_chapter?}", article.lastchapter);
            result = result.Replace("{?$sortname?}", article.sortname);
            result = result.Replace("{?$sortid?}", article.sortid.ToString(CultureInfo.InvariantCulture));
            result = result.Replace("{?$jieqi_charset?}", _config.Charset);
            result = result.Replace("{?$meta_author?}", _config.Domain);
            result = result.Replace("{?$url_fullpage?}",string.Format("/{0}{1}{2}", article.articleid/1000, article.articleid,_template.JieqiArticleConfigs["htmlfile"]));
            result = result.Replace("{?$url_download?}",string.Format("{0}{1}.zip", article.articleid/1000, article.articleid));
            result = result.Replace("{?$url_fullpage?}",string.Format("{0}{1}", article.articleid, _template.JieqiArticleConfigs["htmlfile"]));
            result = result.Replace("{?$articleid?}", string.Format("{0}", article.articleid));
            result = result.Replace("{?$article_id|subdirectory?}", string.Format("{0}", article.articleid/1000));
            result = result.Replace("{?$articleid|subdirectory?}", string.Format("{0}", article.articleid/1000));
            result = result.Replace("{?$preview_page?}",string.Format("index{0}", _template.JieqiArticleConfigs["htmlfile"]));
            result = result.Replace("{?$next_page?}",string.Format("index{0}", _template.JieqiArticleConfigs["htmlfile"]));
            result = result.Replace("{?$index_page?}",string.Format("index{0}", _template.JieqiArticleConfigs["htmlfile"]));
            result = result.Replace("{?$article_id?}", string.Format("{0}",article.articleid));
            result = result.Replace("{?$chapter_id?}", string.Format("{0}", article.lastchapterid));
            result = result.Replace("{?$articleid?}", string.Format("{0}", article.articleid));
            result = result.Replace("{?$articlesubdir?}", string.Format("/{0}", article.articleid/1000));
            result = result.Replace("{?$chapterid?}", string.Format("{0}", article.lastchapterid));
            result = result.Replace("{?$url_bookroom?}",string.Format("{0}/modules/article/", _template.JieqiDefine["JIEQI_URL"]));
            if (string.IsNullOrEmpty(_template.JieqiArticleConfigs["fakeinfo"]))
                result = result.Replace("{?$url_articleinfo?}",string.Format("{0}/modules/article/articleinfo.php?id=" + article.articleid,_template.JieqiDefine["JIEQI_URL"]));
            if(string.IsNullOrEmpty(_template.JieqiArticleConfigs["fakeprefix"]))
            {
                result = result.Replace("{?$url_articleinfo?}",
                                        string.Format("{0}/files/article/info/{1}/{2}",
                                                      _template.JieqiDefine["JIEQI_URL"], article.articleid/1000,
                                                      article.articleid, _template.JieqiArticleConfigs["fakefile"]));
            }
            else
            {
                result = result.Replace("{?$url_articleinfo?}",
                                        string.Format("{0}/{1}info/{2}/{3}{4}", _template.JieqiDefine["fakeprefix"],
                                                      article.articleid/1000, article.articleid,
                                                      _template.JieqiArticleConfigs["fakefile"]));
            }
            result = result.Replace("{novelname}", article.articlename);
            result = result.Replace("{NovelName}", article.articlename);
            result = result.Replace("{?$articlename|urlencode?}", "");
            return result;
        }

        public bool CreateIndexHtml(ArticleInfo article, IEnumerable<ChapterInfo> chapters)
        {
            var num2 = 1;
            var newValue = "";
            var str6 = string.Format("{0}{1}{2}", _template.TempletsIndextop, _template.TempletsIndexchapter,
                                        _template.TempletsIndexbottom);
            string str9 = "", str10 = "", str11 = "0", str13 = "";
            string path = "", str15 = "";
            string strTemp;
            foreach (ChapterInfo chapter in chapters)
            {
                chapter.chaptername = ReplaceInvalidValue(1, chapter.chaptername);
                int num3 = chapter.chaptertype;
                if(num3==1)
                {
                    if (num2 != 1) newValue += str6;
                    newValue += _template.TempletsIndextop;
                    if(string.IsNullOrEmpty(chapter.chaptername))
                    {
                        str13 = str13.Replace("章节vname", _template.TempletsIndexchapterlist["vname"][0]);
                        str13 = str13.Replace("{?$indexrows[i].vname?}", chapter.chaptername);
                        str13 = str13.Replace("{?$indexrows[i].vid?}", string.Format("{0}", chapter.chapterid));
                        newValue += str13;
                    }
                    else
                    {
                        string str14 = _template.TempletsIndexvolume;
                        str14 = str14.Replace("章节vname", _template.TempletsIndexchapterlist["vname"][1]);
                        str14 = str14.Replace("{?$indexrows[i].vname?}", chapter.chaptername);
                        str14 = str14.Replace("{?$indexrows[i].vid?}", string.Format("{0}", chapter.chapterid));
                        newValue += str14;
                    }
                    newValue += _template.TempletsIndexbottom;
                    num2 = 1;
                }//if(num3==1) end
                else
                {
                    str10 = chapter.chaptername;
                    str11 = string.Format("{0}", chapter.chapterid);
                    if(!_template.TempletsIndexchapterlist.ContainsKey(string.Format("cname{0}",num2)))
                    {
                        num2 = 1;
                        newValue = newValue + str6;
                    }
                    if (num2 == 1)
                    {
                        str6 = string.Format("{0}{1}{2}", _template.TempletsIndextop, _template.TempletsIndexchapter,
                                             _template.TempletsIndexbottom);
                    }
                    str6 = str6.Replace(string.Format("章节cname{0}", num2), string.IsNullOrEmpty(chapter.chaptername) ?
                        _template.TempletsIndexchapterlist[string.Format("cname{0}", num2)][0] : 
                        _template.TempletsIndexchapterlist[string.Format("cname{0}", num2)][1]);
                    str6 = str6.Replace("{?$indexrows[i].cname" + num2.ToString(CultureInfo.InvariantCulture) + "?}", chapter.chaptername);
                    str6 = str6.Replace("{?$indexrows[i].curl" + num2.ToString(CultureInfo.InvariantCulture) + "?}",
                                        string.Format("{0}{1}", chapter.chapterid,
                                                      _template.JieqiArticleConfigs["htmlfile"]));
                    str6 = str6.Replace("{?$indexrows[i].cid" + num2.ToString(CultureInfo.InvariantCulture) + "?}",
                                        string.Format("{0}", chapter.chapterid));

                    num2++;
                    if(num2>_indexCols)
                    {
                        newValue += str6;
                        num2 = 1;
                    }
                }
            }//for end
            if (num2 != 1) newValue += str6;
            for (int i = 1; i < _indexCols; i++)
                newValue = newValue.Replace(string.Format("章节cname{0}", i), "&nbsp;");

            string str18 = _template.TempletsIndexhtml;
            str18 = str18.Replace("目录循环部分", newValue);
            str18 = ReplaceTemplate(str18, article);
            str18 = str18.Replace("{?$lastchapter?}", str10);
            str18 = str18.Replace("{?$url_lastchapter?}",
                                  string.Format("{0}{1}", str11, _template.JieqiArticleConfigs["htmlfile"]));
            string str19 = string.Format("{0}/{1}/{2}", _template.HtmlDir, article.articleid/1000, article.articleid);
            if (!System.IO.Directory.Exists(str19))
                System.IO.Directory.CreateDirectory(str19);
            str19 += string.Format("/index{0}", _template.JieqiArticleConfigs["htmlfile"]);
            return XFile.WriteFile(str19, str18);
        }
    }
}